//
//  NSString+ZZ.swift
//  KeDaLeDaoHang
//
//  Created by 陈钟 on 2019/5/10.
//  Copyright © 2019 陈钟. All rights reserved.
//

import Foundation
import UIKit
import CommonCrypto

public extension String{
    var md5: String {
        let utf8 = cString(using: .utf8)
        var digest = [UInt8](repeating: 0, count: Int(CC_MD5_DIGEST_LENGTH))
        CC_MD5(utf8, CC_LONG(utf8!.count - 1), &digest)
        return digest.reduce("") { $0 + String(format:"%02X", $1) }
    }

    var lastString: String{
        if self.count <= 0 { return self }
        return self.substring(from: self.count - 1)
    }

    var firstString: String{
        if self.count <= 0 { return self }
        return self.substring(to: 1)
    }

    func substring(from index: Int) -> String {
        if self.count > index {
            let startIndex = self.index(self.startIndex, offsetBy: index)
            let subString = self[startIndex..<self.endIndex]
            
            return String(subString)
        } else {
            return self
        }
    }
    
    func substring(to index: Int) -> String {
        if self.count > index {
            let endIndex = self.index(self.startIndex, offsetBy: index)
            let subString = self[self.startIndex..<endIndex]
            return String(subString)
        } else {
            return self
        }
    }
    
    func substring(range index: NSRange) -> String {
        if self.count > index.length {
            let startIndex = self.index(self.startIndex, offsetBy: index.location)
            let endIndex = self.index(self.startIndex, offsetBy: index.location + index.length)
            let subString = self[startIndex..<endIndex]
            return String(subString)
        } else {
            return self
        }
    }
    
    func hidden(range index: NSRange, replace: String = "*") -> String {
        if self.count > (index.length + index.location) {
            var toStr = self.substring(to: index.location)
            let fromStr = self.substring(from: index.location + index.length)
            for _ in 0 ..< index.length{
                toStr.append(replace)
            }
            return "\(toStr)\(fromStr)"
        } else {
            return self
        }
    }

    func jsonFormatPrint() -> String {

        if (self.starts(with: "{") || self.starts(with: "[")){
            var level = 0
            var jsonFormatString = String()

            func getLevelStr(level:Int) -> String {
                var string = ""
                for _ in 0..<level {
                    string.append("\t")
                }
                return string
            }

            for char in self {
                if level > 0 && "\n" == jsonFormatString.last {
                    jsonFormatString.append(getLevelStr(level: level))
                }
                switch char {
                    case "{":
                        fallthrough
                    case "[":
                        level += 1
                        jsonFormatString.append(char)
                        jsonFormatString.append("\n")
                    case ",":
                        jsonFormatString.append(char)
                        jsonFormatString.append("\n")
                    case "}":
                        fallthrough
                    case "]":
                        level -= 1;
                        jsonFormatString.append("\n")
                        jsonFormatString.append(getLevelStr(level: level));
                        jsonFormatString.append(char);
                        break;
                    default:
                        jsonFormatString.append(char)
                }
            }
            return jsonFormatString;
        }

        return self
    }

    func intValue() -> Int{
        if self.count == 0 {
            return 0
        }
        return Int(self) ?? 0
    }
    func doubleValue() -> Double{
        return Double(self) ?? 0
    }
    func floatValue() -> CGFloat {
        return CGFloat(Double(self) ?? 0)
    }
    
    /// 判断是否是手机号码
    func isPhone() -> Bool {
        /*
         移动号段
         139 138 137 136 134 135 147 150 151 152 157 158 159 172 178 182 183 184 187 188 195 197 198
         联通号段
         130 131 132 140 145 146 155 156 166 167 185 186 175 176
         电信号段
         133 149 153 177 173 180 181 189 191 199
         虚拟运营商号段
         162 165 170 171
        */
        let phoneRegex = "^1(3[0-9]|4[0,5,6,7,9]|5[^4,\\D]|6[2,5,6,7]|7[^4,\\D]|8[0-9]|9[1,2,5,8,9])\\d{8}"
        let phonePredicate = NSPredicate.init(format: "SELF MATCHES %@", phoneRegex)
        return phonePredicate.evaluate(with: self)
    }

    /// 是否是固话
    func isTelPhone() -> Bool {
        let phoneRegex = "^(0\\d{2,3}-? ?\\d{7,8}$)"
        let phonePredicate = NSPredicate.init(format: "SELF MATCHES %@", phoneRegex)
        let isPhone1 = phonePredicate.evaluate(with: self)

        let phoneRegex2 = "^(\\d{7,8}$)"
        let phonePredicate2 = NSPredicate.init(format: "SELF MATCHES %@", phoneRegex2)
        let isPhone2 = phonePredicate2.evaluate(with: self)

        if isPhone1 || isPhone2 {
            return true
        }
        return false
    }

    /// 判断是否是身份证号码
    func isIdCard() -> Bool{

        let value = self.trimmingCharacters(in: CharacterSet.whitespacesAndNewlines)

        let length = value.count
        if length != 15 && length != 18 {
            return false
        }

        let areasArr = ["11","12", "13","14", "15","21", "22","23", "31","32", "33","34", "35","36", "37","41", "42","43", "44","45", "46","50", "51","52", "53","54", "61","62", "63","64", "65","71", "81","82", "91"]

        let valueStart2 = value.substring(to: 2)
        var areaFlag = false
        for areaCode in areasArr {
            if areaCode == valueStart2{
                areaFlag = true
                break
            }
        }
        if !areaFlag { return false }

        var regularExpression: NSRegularExpression
        var numberofMatch: Int

        var year: Int = 0

        switch length {
            case 15:
                year = value.substring(range: NSRange(location: 6, length: 2)).intValue() + 1900
                if year % 4 == 0 || (year % 100 == 0 && year % 4 == 0) {
                    //测试出生日期的合法性
                    regularExpression = try! NSRegularExpression.init(pattern: "^[1-9][0-9]{5}[0-9]{2}((01|03|05|07|08|10|12)(0[1-9]|[1-2][0-9]|3[0-1])|(04|06|09|11)(0[1-9]|[1-2][0-9]|30)|02(0[1-9]|[1-2][0-9]))[0-9]{3}$", options: .caseInsensitive)
                }else{
                    //测试出生日期的合法性
                    regularExpression = try! NSRegularExpression.init(pattern: "^[1-9][0-9]{5}[0-9]{2}((01|03|05|07|08|10|12)(0[1-9]|[1-2][0-9]|3[0-1])|(04|06|09|11)(0[1-9]|[1-2][0-9]|30)|02(0[1-9]|1[0-9]|2[0-8]))[0-9]{3}$", options: .caseInsensitive)
                }
                numberofMatch = regularExpression.numberOfMatches(in: value, options: .reportProgress, range: NSMakeRange(0, value.count))
                if numberofMatch > 0 {
                    return true
                }
                return false
            case 18:
                year = value.substring(range: NSRange(location: 6, length: 4)).intValue()
                if year % 4 == 0 || (year % 100 == 0 && year % 4 == 0) {
                    //测试出生日期的合法性
                    regularExpression = try! NSRegularExpression.init(pattern: "^((1[1-5])|(2[1-3])|(3[1-7])|(4[1-6])|(5[0-4])|(6[1-5])|71|(8[12])|91)\\d{4}(((19|20)\\d{2}(0[13-9]|1[012])(0[1-9]|[12]\\d|30))|((19|20)\\d{2}(0[13578]|1[02])31)|((19|20)\\d{2}02(0[1-9]|1\\d|2[0-8]))|((19|20)([13579][26]|[2468][048]|0[048])0229))\\d{3}(\\d|X|x)?$", options: .caseInsensitive)
                }else{
                    //测试出生日期的合法性
                    regularExpression = try! NSRegularExpression.init(pattern: "^((1[1-5])|(2[1-3])|(3[1-7])|(4[1-6])|(5[0-4])|(6[1-5])|71|(8[12])|91)\\d{4}(((19|20)\\d{2}(0[13-9]|1[012])(0[1-9]|[12]\\d|30))|((19|20)\\d{2}(0[13578]|1[02])31)|((19|20)\\d{2}02(0[1-9]|1\\d|2[0-8]))|((19|20)([13579][26]|[2468][048]|0[048])0229))\\d{3}(\\d|X|x)?$", options: .caseInsensitive)
                }
                numberofMatch = regularExpression.numberOfMatches(in: value, options: .reportProgress, range: NSMakeRange(0, value.count))
                if numberofMatch > 0 {
                    //1：校验码的计算方法 身份证号码17位数分别乘以不同的系数。从第一位到第十七位的系数分别为：7－9－10－5－8－4－2－1－6－3－7－9－10－5－8－4－2。将这17位数字和系数相乘的结果相加。
                    let S = value.substring(range: NSMakeRange(0, 1)).intValue() * 7 +
                        value.substring(range: NSMakeRange(10, 1)).intValue() * 7 +
                        value.substring(range: NSMakeRange(1, 1)).intValue() * 9 +
                        value.substring(range: NSMakeRange(11, 1)).intValue() * 9 +
                        value.substring(range: NSMakeRange(2, 1)).intValue() * 10 +
                        value.substring(range: NSMakeRange(12, 1)).intValue() * 10 +
                        value.substring(range: NSMakeRange(3, 1)).intValue() * 5 +
                        value.substring(range: NSMakeRange(13, 1)).intValue() * 5 +
                        value.substring(range: NSMakeRange(4, 1)).intValue() * 8 +
                        value.substring(range: NSMakeRange(14, 1)).intValue() * 8 +
                        value.substring(range: NSMakeRange(5, 1)).intValue() * 4 +
                        value.substring(range: NSMakeRange(15, 1)).intValue() * 4 +
                        value.substring(range: NSMakeRange(6, 1)).intValue() * 2 +
                        value.substring(range: NSMakeRange(16, 1)).intValue() * 2 +
                        value.substring(range: NSMakeRange(7, 1)).intValue() * 1 +
                        value.substring(range: NSMakeRange(8, 1)).intValue() * 6 +
                        value.substring(range: NSMakeRange(9, 1)).intValue() * 3


                    //2：用加出来和除以11，看余数是多少？余数只可能有0－1－2－3－4－5－6－7－8－9－10这11个数字
                    let Y = S % 11
                    var M = "F"
                    let JYM = "10X98765432"

                    M = JYM.substring(range: NSMakeRange(Y, 1))

                    let lastString = value.substring(range: NSMakeRange(17, 1))
                    if lastString == "x" {
                        if M == "X" {
                            return true
                        }else {
                            return false
                        }
                    }else{
                        if M == value.substring(range: NSMakeRange(17, 1)) {
                            return true
                        }else{
                            return false
                        }
                    }
                }
                return false
            default: return false
        }
    }
    
    ///判断是否是6位验证码
    func isCode_6()  -> Bool{
        let phoneRegex = "\\d{6}"
        let phonePredicate = NSPredicate.init(format: "SELF MATCHES %@", phoneRegex)
        return phonePredicate.evaluate(with: self)
    }
    /// 判断字符位数
    func isLength(minLength:Int, maxLenter:Int)  -> Bool{
        let phoneRegex = "\\w{\(minLength),\(maxLenter)}"
        let phonePredicate = NSPredicate.init(format: "SELF MATCHES %@", phoneRegex)
        return phonePredicate.evaluate(with: self)
    }
    
}
